package com.cloudcentral.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudcentral.entity.Role;
import com.cloudcentral.entity.User;
import com.cloudcentral.entity.UserRole;
import com.cloudcentral.entity.vo.UserDetailVO;
import com.cloudcentral.mapper.PlatformBaseMapper;
import com.cloudcentral.mapper.RoleBaseMapper;
import com.cloudcentral.mapper.UserBaseMapper;
import com.cloudcentral.mapper.UserRoleBaseMapper;
import com.cloudcentral.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Create by Administrator
 * 2023/11/9 15:28
 */
@Slf4j
@Service
public class UserService extends ServiceImpl<UserBaseMapper, User> implements UserDetailsService {
  private final UserRoleBaseMapper userRoleMapper;
  private final RoleBaseMapper roleMapper;
  private final PlatformBaseMapper platformBaseMapper;

  @Autowired
  public UserService(UserRoleBaseMapper userRoleMapper, RoleBaseMapper roleMapper, PlatformBaseMapper platformBaseMapper) {
    this.userRoleMapper = userRoleMapper;
    this.roleMapper = roleMapper;
    this.platformBaseMapper = platformBaseMapper;
  }

  public User getUser(String name) {
    return baseMapper.selectUser(name);
  }

  public OidcUserInfo loadUserInfo(String name, Set<String> scopes) {
    if (StringUtils.isBlank(name)) throw new UsernameNotFoundException("缺少名称");
    else {
      User user = baseMapper.selectUser(name);
      if (user == null) throw new UsernameNotFoundException("用户不存在");
      else {
        OidcUserInfo.Builder builder = OidcUserInfo.builder();
        if (scopes.contains(OidcScopes.OPENID)) {
          builder.claims(map -> {
            map.put("id", user.getId());
            map.put("platform", platformBaseMapper.selectById(user.getPlatformId()));
          });
        }
        if (scopes.contains(OidcScopes.PROFILE)) {
          builder.claims(map -> {
            map.put("username", user.getUsername());
            map.put("avatar", user.getAvatar());
            map.put("gender", user.getGender());
            map.put("age", user.getAge());
            map.put("remark", user.getRemark());
            map.put("registerTime", DateUtils.dateFormat(user.getRegisterTime()));
            map.put("auditTime", DateUtils.dateFormat(user.getAuditTime()));
          });
        }
        if (scopes.contains(OidcScopes.PHONE)) builder.claim("phone", user.getPhone());
        return builder.build();
      }
    }
  }

  @Override
  public UserDetailVO loadUserByUsername(String name) throws UsernameNotFoundException {
    if (StringUtils.isBlank(name)) throw new UsernameNotFoundException("缺少名称");
    else {
      User user = baseMapper.selectUser(name);
      if (user == null) throw new UsernameNotFoundException("用户不存在");
      else if (!user.getEnable()) throw new UsernameNotFoundException("用户已冻结");
      else {
        List<GrantedAuthority> authorities = new ArrayList<>();
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.eq("user_id", user.getId());
        UserRole userRole = userRoleMapper.selectOne(userRoleQueryWrapper);
        if (userRole != null) {
          Role role = roleMapper.selectById(userRole.getRoleId());
          authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return UserDetailVO.builder()
            .phone(user.getPhone())
            .username(user.getUsername())
            .password(user.getPassword())
            .authorities(authorities)
            .accountNonExpired(true)
            .accountNonLocked(true)
            .credentialsNonExpired(true)
            .enabled(user.getEnable())
            .build();
      }
    }
  }
}
